home *** CD-ROM | disk | FTP | other *** search
Text File | 2000-10-06 | 31.8 KB | 952 lines | [TEXT/CWIE] |
- ///--------------------------------------------------------------------------------------
- // Multi-Screen Scrolling.c
- //
- // By Vern Jensen. Created 1/1/97
- ///--------------------------------------------------------------------------------------
-
-
- #ifndef __SPRITEWORLD__
- #include <SpriteWorld.h>
- #endif
-
- #ifndef __SPRITEWORLDUTILS__
- #include <SpriteWorldUtils.h>
- #endif
-
- #ifndef __SCROLLING__
- #include <Scrolling.h>
- #endif
-
- #ifndef __TILING__
- #include <Tiling.h>
- #endif
-
- #ifndef __MULTISCREENSCROLLING__
- #include <Multi-Screen Scrolling.h>
- #endif
-
-
- ///--------------------------------------------------------------------------------------
- // SWSetUpDuplicateSpriteWorld
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWSetUpDuplicateSpriteWorld(
- SpriteWorldPtr masterSpriteWorldP,
- SpriteWorldPtr duplicateSpriteWorldP)
- {
- FramePtr dupFrameP;
-
- // Dispose the deadSpriteLayer of the duplicateSpriteWorldP
- SWDisposeSpriteLayer(&duplicateSpriteWorldP->deadSpriteLayerP);
-
- // Share SpriteLayers
- duplicateSpriteWorldP->headSpriteLayerP = masterSpriteWorldP->headSpriteLayerP;
- duplicateSpriteWorldP->tailSpriteLayerP = masterSpriteWorldP->tailSpriteLayerP;
- duplicateSpriteWorldP->deadSpriteLayerP = masterSpriteWorldP->deadSpriteLayerP;
-
- // Copy DrawProc info and scrollRectMoveBounds
- duplicateSpriteWorldP->offscreenDrawProc = masterSpriteWorldP->offscreenDrawProc;
- duplicateSpriteWorldP->screenDrawProc = masterSpriteWorldP->screenDrawProc;
- duplicateSpriteWorldP->doubleRectDrawProc = masterSpriteWorldP->doubleRectDrawProc;
- duplicateSpriteWorldP->scrollRectMoveBounds = masterSpriteWorldP->scrollRectMoveBounds;
-
- // Copy interlacing information for back, work, window, and extra frames.
- dupFrameP = duplicateSpriteWorldP->backFrameP;
- if (dupFrameP != NULL && masterSpriteWorldP->backFrameP != NULL)
- {
- dupFrameP->interlacingIsOn = masterSpriteWorldP->backFrameP->interlacingIsOn;
- dupFrameP->skipOddLines = masterSpriteWorldP->backFrameP->skipOddLines;
- }
-
- dupFrameP = duplicateSpriteWorldP->workFrameP;
- if (dupFrameP != NULL && masterSpriteWorldP->workFrameP != NULL)
- {
- dupFrameP->interlacingIsOn = masterSpriteWorldP->workFrameP->interlacingIsOn;
- dupFrameP->skipOddLines = masterSpriteWorldP->workFrameP->skipOddLines;
- }
-
- dupFrameP = duplicateSpriteWorldP->windowFrameP;
- if (dupFrameP != NULL && masterSpriteWorldP->windowFrameP != NULL)
- {
- dupFrameP->interlacingIsOn = masterSpriteWorldP->windowFrameP->interlacingIsOn;
- dupFrameP->skipOddLines = masterSpriteWorldP->windowFrameP->skipOddLines;
- }
-
- dupFrameP = duplicateSpriteWorldP->extraBackFrameP;
- if (dupFrameP != NULL && masterSpriteWorldP->extraBackFrameP != NULL)
- {
- dupFrameP->interlacingIsOn = masterSpriteWorldP->extraBackFrameP->interlacingIsOn;
- dupFrameP->skipOddLines = masterSpriteWorldP->extraBackFrameP->skipOddLines;
- }
-
- // Copy tiling stuff
- duplicateSpriteWorldP->extraBackFrameP = masterSpriteWorldP->extraBackFrameP;
- duplicateSpriteWorldP->tileLayerArray = masterSpriteWorldP->tileLayerArray;
- duplicateSpriteWorldP->lastActiveTileLayer = masterSpriteWorldP->lastActiveTileLayer;
- duplicateSpriteWorldP->tileRectDrawProc = masterSpriteWorldP->tileRectDrawProc;
- duplicateSpriteWorldP->tileFrameArray = masterSpriteWorldP->tileFrameArray;
- duplicateSpriteWorldP->curTileImage = masterSpriteWorldP->curTileImage;
- duplicateSpriteWorldP->maxNumTiles = masterSpriteWorldP->maxNumTiles;
- duplicateSpriteWorldP->tileWidth = masterSpriteWorldP->tileWidth;
- duplicateSpriteWorldP->tileHeight = masterSpriteWorldP->tileHeight;
- duplicateSpriteWorldP->tileMaskDrawProc = masterSpriteWorldP->tileMaskDrawProc;
- duplicateSpriteWorldP->partialMaskDrawProc = masterSpriteWorldP->partialMaskDrawProc;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWDisposeDuplicateSpriteWorld
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWDisposeDuplicateSpriteWorld(
- SpriteWorldPtr spriteWorldP)
- {
- if (spriteWorldP != NULL)
- {
- SWUnlockSpriteWorld(spriteWorldP);
-
- SWDisposeFrame(&spriteWorldP->backFrameP);
- SWDisposeFrame(&spriteWorldP->workFrameP);
- SWDisposeWindowFrame(&spriteWorldP->windowFrameP);
-
- SWExitTilingForDuplicateSpriteWorld(spriteWorldP);
- SWSyncSpriteWorldToVBL(spriteWorldP, false);
-
- DisposePtr((Ptr)spriteWorldP);
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWInitTilingForDuplicateSpriteWorld
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWInitTilingForDuplicateSpriteWorld(
- SpriteWorldPtr spriteWorldP,
- short tileHeight,
- short tileWidth)
- {
- OSErr err = noErr;
-
-
- if (spriteWorldP->tilingIsInitialized)
- {
- err = kTilingAlreadyInitialized;
- }
-
- if (err == noErr)
- {
- spriteWorldP->tilingIsOn = true;
- spriteWorldP->tilingIsInitialized = true;
- // spriteWorldP->lastActiveTileLayer = 0; // <-- Copied from master SpriteWorld
- // spriteWorldP->maxNumTiles = maxNumTiles; // <-- Copied from master SpriteWorld
- spriteWorldP->tileHeight = tileHeight;
- spriteWorldP->tileWidth = tileWidth;
- }
-
- if (err == noErr)
- {
- // Create both tiling cache and changedTiles array of rects
- // (We need the changedTilesArray even for a duplicate SpriteWorld.)
- err = SWInitTilingCache(spriteWorldP);
- }
-
-
- SWSetStickyIfError(err);
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWExitTilingForDuplicateSpriteWorld
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWExitTilingForDuplicateSpriteWorld(
- SpriteWorldPtr spriteWorldP)
- {
- // Was tiling ever initialized?
- if (spriteWorldP->tilingIsInitialized)
- {
- DisposePtr((Ptr)spriteWorldP->changedTiles);
- DisposePtr((Ptr)spriteWorldP->tilingCache[0]); // Dispose the data
- DisposePtr((Ptr)spriteWorldP->tilingCache); // Dispose the array of pointers
-
- spriteWorldP->tilingIsInitialized = false;
- spriteWorldP->tilingIsOn = false;
- }
- }
-
-
- #pragma mark -
- ///--------------------------------------------------------------------------------------
- // SWProcessMultiScreenSpriteWorld
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWProcessMultiScreenSpriteWorld(
- SpriteWorldPtr spriteWorldP)
- {
- gSWCurrentSpriteWorld = spriteWorldP;
-
- // Call the scrolling world move proc
- if (spriteWorldP->worldMoveProc != NULL)
- {
- (*spriteWorldP->worldMoveProc)(spriteWorldP, spriteWorldP->followSpriteP);
- }
-
-
- // Move visScrollRect
- if (spriteWorldP->horizScrollDelta || spriteWorldP->vertScrollDelta)
- {
- SWOffsetVisScrollRect(spriteWorldP,
- spriteWorldP->horizScrollDelta,
- spriteWorldP->vertScrollDelta);
- }
-
- gSWCurrentSpriteWorld = NULL;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWFinishProcessingMultiScreenSW
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWFinishProcessingMultiScreenSW(
- SpriteWorldPtr spriteWorldP)
- {
- gSWCurrentSpriteWorld = spriteWorldP;
-
- // Process any Sprites in a non-scrolling SpriteLayer
- SWProcessNonScrollingLayers(spriteWorldP);
-
- gSWCurrentSpriteWorld = NULL;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWAnimateMultiScreenSpriteWorld. The only differences between this function
- // and the normal SWAnimateScrollingSpriteWorld are:
- // A) The code that assigns the destFrameRect to the oldFrameRect, etc. was moved to
- // SWFinishMultiScreenAnimation where applicable.
- // B) The code at the very beginning of this function that checks the frameHasOccurred
- // variable was removed, since the user has to do this for multi-screen animations.
- // C) The name was changed. :-)
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWAnimateMultiScreenSpriteWorld(
- SpriteWorldPtr spriteWorldP)
- {
- UpdateRectStructPtr curRectStructP,
- nextRectStructP;
- register SpriteLayerPtr curSpriteLayerP;
- register SpritePtr curSpriteP;
- SpritePtr headActiveSpriteP = NULL; // Tail of active sprite list
- SpritePtr headIdleSpriteP = NULL; // Tail of idle sprite list
- SpritePtr curActiveSpriteP = NULL;
- SpritePtr curIdleSpriteP = NULL;
- Rect *visScrollRectP = &spriteWorldP->visScrollRect;
- Rect tempDstRect, tempSrcRect;
- short hScrollDelta, vScrollDelta, curTileLayer;
- short oldVertScrollRectOffset, oldHorizScrollRectOffset;
-
- SW_ASSERT(spriteWorldP != NULL);
- SW_ASSERT(spriteWorldP->backFrameP->isFrameLocked);
- SW_ASSERT(spriteWorldP->workFrameP->isFrameLocked);
- SW_ASSERT(spriteWorldP->windowFrameP->isFrameLocked);
-
- gSWCurrentSpriteWorld = spriteWorldP;
-
- oldVertScrollRectOffset = spriteWorldP->backRect.bottom *
- (spriteWorldP->oldVisScrollRect.top / spriteWorldP->backRect.bottom);
-
- oldHorizScrollRectOffset = spriteWorldP->backRect.right *
- (spriteWorldP->oldVisScrollRect.left / spriteWorldP->backRect.right);
-
-
- // Add the deadSpriteLayer if there are any Sprites in it.
- if ( spriteWorldP->deadSpriteLayerP->headSpriteP != NULL )
- {
- SWAddSpriteLayer(spriteWorldP, spriteWorldP->deadSpriteLayerP);
- }
-
-
- hScrollDelta = visScrollRectP->left - spriteWorldP->oldVisScrollRect.left;
- vScrollDelta = visScrollRectP->top - spriteWorldP->oldVisScrollRect.top;
-
-
- // Update tiles as we scroll if tiling is turned on
- if (spriteWorldP->tilingIsOn)
- {
- // VisScrollRect moved horizontally
- if (hScrollDelta)
- {
- // Get rect of new vertical section to update
- tempDstRect = *visScrollRectP;
-
- // Moved left
- if (hScrollDelta < 0)
- {
- if (tempDstRect.right > spriteWorldP->oldVisScrollRect.left)
- tempDstRect.right = spriteWorldP->oldVisScrollRect.left;
- }
- else // Moved right
- {
- if (tempDstRect.left < spriteWorldP->oldVisScrollRect.right)
- tempDstRect.left = spriteWorldP->oldVisScrollRect.right;
- }
-
- (*spriteWorldP->tileRectDrawProc)(spriteWorldP, &tempDstRect, true);
- SWWrapRectToWorkArea(spriteWorldP, &tempDstRect);
-
-
- // Did VisScrollRect moved diagonally?
- if (vScrollDelta)
- {
- // Get rect of new horizontal section to update
- tempDstRect = spriteWorldP->visScrollRect;
-
- // Moved up
- if (vScrollDelta < 0)
- {
- if (tempDstRect.bottom > spriteWorldP->oldVisScrollRect.top)
- tempDstRect.bottom = spriteWorldP->oldVisScrollRect.top;
- }
- else // Moved down
- {
- if (tempDstRect.top < spriteWorldP->oldVisScrollRect.bottom)
- tempDstRect.top = spriteWorldP->oldVisScrollRect.bottom;
- }
-
- // Clip off the part we've already updated
- if (hScrollDelta < 0)
- {
- if (tempDstRect.left < spriteWorldP->oldVisScrollRect.left)
- tempDstRect.left = spriteWorldP->oldVisScrollRect.left;
- }
- else
- {
- if (tempDstRect.right > spriteWorldP->oldVisScrollRect.right)
- tempDstRect.right = spriteWorldP->oldVisScrollRect.right;
- }
-
- // We pass false here to avoid a bug which occured in the
- // tile optimizing code when updating tiles twice in one frame
- if (tempDstRect.right > tempDstRect.left)
- {
- (*spriteWorldP->tileRectDrawProc)(spriteWorldP, &tempDstRect, false);
- SWWrapRectToWorkArea(spriteWorldP, &tempDstRect);
- }
- }
- } // VisScrollRect moved vertically only
- else if (vScrollDelta)
- {
- // Get rect of new horizontal section to update
- tempDstRect = *visScrollRectP;
-
- // Moved up
- if (vScrollDelta < 0)
- {
- if (tempDstRect.bottom > spriteWorldP->oldVisScrollRect.top)
- tempDstRect.bottom = spriteWorldP->oldVisScrollRect.top;
- }
- else // Moved down
- {
- if (tempDstRect.top < spriteWorldP->oldVisScrollRect.bottom)
- tempDstRect.top = spriteWorldP->oldVisScrollRect.bottom;
- }
-
- (*spriteWorldP->tileRectDrawProc)(spriteWorldP, &tempDstRect, true);
- SWWrapRectToWorkArea(spriteWorldP, &tempDstRect);
- }
- }
-
-
- //-----------------erase the sprites--------------------
-
- // Set the port to the work area so we can draw in it
- SetGWorld(spriteWorldP->workFrameP->framePort, nil);
-
- curSpriteLayerP = spriteWorldP->headSpriteLayerP;
- curTileLayer = 0;
-
- // iterate through the layers in this world
- while (curSpriteLayerP != NULL)
- {
- curSpriteP = curSpriteLayerP->headSpriteP;
-
- if (curSpriteLayerP->tileLayer > curTileLayer)
- curTileLayer = curSpriteLayerP->tileLayer;
-
- // iterate through the sprites in this layer
- while (curSpriteP != NULL)
- {
- SW_ASSERT(curSpriteP->curFrameP->isFrameLocked);
- curSpriteP->tileDepth = curTileLayer;
-
- // Clip the sprite's destOffscreenRect with visScrollRect.
- if (curSpriteP->isVisible)
- {
- curSpriteP->destOffscreenRect = curSpriteP->destFrameRect;
- curSpriteP->clippedSourceRect = curSpriteP->curFrameP->frameRect;
-
-
- if (curSpriteP->destOffscreenRect.top < visScrollRectP->top)
- {
- curSpriteP->clippedSourceRect.top += visScrollRectP->top -
- curSpriteP->destOffscreenRect.top;
- curSpriteP->destOffscreenRect.top = visScrollRectP->top;
- }
-
- if (curSpriteP->destOffscreenRect.bottom > visScrollRectP->bottom)
- {
- curSpriteP->clippedSourceRect.bottom += visScrollRectP->bottom -
- curSpriteP->destOffscreenRect.bottom;
- curSpriteP->destOffscreenRect.bottom = visScrollRectP->bottom;
- }
-
- if (curSpriteP->destOffscreenRect.left < visScrollRectP->left)
- {
- curSpriteP->clippedSourceRect.left += visScrollRectP->left -
- curSpriteP->destOffscreenRect.left;
- curSpriteP->destOffscreenRect.left = visScrollRectP->left;
- }
-
- if (curSpriteP->destOffscreenRect.right > visScrollRectP->right)
- {
- curSpriteP->clippedSourceRect.right += visScrollRectP->right -
- curSpriteP->destOffscreenRect.right;
- curSpriteP->destOffscreenRect.right = visScrollRectP->right;
- }
-
- curSpriteP->destRectIsVisible =
- (curSpriteP->destOffscreenRect.right >
- curSpriteP->destOffscreenRect.left &&
- curSpriteP->destOffscreenRect.bottom >
- curSpriteP->destOffscreenRect.top);
- }
-
-
- // Erase the sprites
- if (curSpriteP->needsToBeDrawn && curSpriteP->isVisible ||
- curSpriteP->needsToBeErased && !curSpriteP->isVisible)
- {
- // Recalculate the oldOffscreenRect (tempDstRect) from scratch. We can't save the
- // destOffscreenRect from the previous frame, since an invisible Sprite that
- // is made visible many frames later could have an incorrect oldOffscreenRect,
- // meaning the Sprite would be erased even if it's not currently on the screen.
-
- tempDstRect = curSpriteP->oldFrameRect;
-
- if (tempDstRect.top < spriteWorldP->oldVisScrollRect.top)
- tempDstRect.top = spriteWorldP->oldVisScrollRect.top;
-
- if (tempDstRect.bottom > spriteWorldP->oldVisScrollRect.bottom)
- tempDstRect.bottom = spriteWorldP->oldVisScrollRect.bottom;
-
- if (tempDstRect.left < spriteWorldP->oldVisScrollRect.left)
- tempDstRect.left = spriteWorldP->oldVisScrollRect.left;
-
- if (tempDstRect.right > spriteWorldP->oldVisScrollRect.right)
- tempDstRect.right = spriteWorldP->oldVisScrollRect.right;
-
- // Was the sprite visible on the screen last frame?
- if (tempDstRect.right > tempDstRect.left &&
- tempDstRect.bottom > tempDstRect.top)
- {
- // Make the tempDstRect local to the offscreen area
- tempDstRect.top -= oldVertScrollRectOffset;
- tempDstRect.bottom -= oldVertScrollRectOffset;
- tempDstRect.left -= oldHorizScrollRectOffset;
- tempDstRect.right -= oldHorizScrollRectOffset;
-
-
- // Add sprite to active sprite list
- if (headActiveSpriteP == NULL)
- headActiveSpriteP = curSpriteP;
-
- if (curActiveSpriteP != NULL)
- curActiveSpriteP->nextActiveSpriteP = curSpriteP;
-
- curActiveSpriteP = curSpriteP;
-
- {
- short temp;
-
- // align left edge of tempDstRect for erasing
- tempDstRect.left &=
- (spriteWorldP->workFrameP->leftAlignFactor);
-
- // align the right edge to long word boundary
- temp = tempDstRect.right &
- spriteWorldP->workFrameP->rightAlignFactor;
- if (temp != 0)
- {
- tempDstRect.right +=
- (spriteWorldP->workFrameP->rightAlignFactor + 1) - temp;
- }
-
- // align left edge of oldFrameRect - necessary for
- // deltaFrameRect below, used by idle sprite collision
- curSpriteP->oldFrameRect.left &=
- (spriteWorldP->workFrameP->leftAlignFactor);
-
- // align the right edge to long word boundary
- temp = curSpriteP->oldFrameRect.right &
- spriteWorldP->workFrameP->rightAlignFactor;
- if (temp != 0)
- {
- curSpriteP->oldFrameRect.right +=
- (spriteWorldP->workFrameP->rightAlignFactor + 1) - temp;
- }
- }
-
- // union last rect and current rect - this is necessary for
- // the proper redrawing of idle sprites
- curSpriteP->deltaFrameRect.top =
- SW_MIN(curSpriteP->oldFrameRect.top, curSpriteP->destFrameRect.top);
- curSpriteP->deltaFrameRect.left =
- SW_MIN(curSpriteP->oldFrameRect.left, curSpriteP->destFrameRect.left);
- curSpriteP->deltaFrameRect.bottom =
- SW_MAX(curSpriteP->oldFrameRect.bottom, curSpriteP->destFrameRect.bottom);
- curSpriteP->deltaFrameRect.right =
- SW_MAX(curSpriteP->oldFrameRect.right, curSpriteP->destFrameRect.right);
-
-
- // Erase the sprite from the work area
- SWEraseWrappedSprite(spriteWorldP, &tempDstRect);
- }
- else if (curSpriteP->destRectIsVisible) // Sprite will be drawn
- {
- // Add sprite to active sprite list
- if (headActiveSpriteP == NULL)
- headActiveSpriteP = curSpriteP;
-
- if (curActiveSpriteP != NULL)
- curActiveSpriteP->nextActiveSpriteP = curSpriteP;
-
- curActiveSpriteP = curSpriteP;
- }
- }
- else if (curSpriteP->isVisible) // Visible, idle sprites
- {
- if (curSpriteP->oldRectIsVisible)
- {
- // Is idle sprite moving outside the visScrollRect?
- if ((hScrollDelta > 0 &&
- (curIdleSpriteP->destFrameRect.left < visScrollRectP->left) &&
- (curIdleSpriteP->destFrameRect.right > spriteWorldP->oldVisScrollRect.left)) ||
- (hScrollDelta < 0 &&
- (curIdleSpriteP->destFrameRect.left < spriteWorldP->oldVisScrollRect.right) &&
- (curIdleSpriteP->destFrameRect.right > visScrollRectP->right)) )
- {
- // Erase piece of idle sprite outside of visScrollRect
- tempDstRect = curSpriteP->oldFrameRect;
-
- // Get section of sprite outside visScrollRect
- if (hScrollDelta > 0)
- {
- if (tempDstRect.right > visScrollRectP->left)
- tempDstRect.right = visScrollRectP->left;
- }
- else
- {
- if (tempDstRect.left < visScrollRectP->right)
- tempDstRect.left = visScrollRectP->right;
- }
-
- // Clip tempDstRect with oldVisScrollRect
- if (tempDstRect.top < spriteWorldP->oldVisScrollRect.top)
- tempDstRect.top = spriteWorldP->oldVisScrollRect.top;
- if (tempDstRect.bottom > spriteWorldP->oldVisScrollRect.bottom)
- tempDstRect.bottom = spriteWorldP->oldVisScrollRect.bottom;
- if (tempDstRect.left < spriteWorldP->oldVisScrollRect.left)
- tempDstRect.left = spriteWorldP->oldVisScrollRect.left;
- if (tempDstRect.right > spriteWorldP->oldVisScrollRect.right)
- tempDstRect.right = spriteWorldP->oldVisScrollRect.right;
-
- // Make the rect local to the offscreen area
- tempDstRect.top -= spriteWorldP->vertScrollRectOffset;
- tempDstRect.bottom -= spriteWorldP->vertScrollRectOffset;
- tempDstRect.left -= spriteWorldP->horizScrollRectOffset;
- tempDstRect.right -= spriteWorldP->horizScrollRectOffset;
-
- SWEraseWrappedSprite(spriteWorldP, &tempDstRect);
- }
-
- // Is idle sprite moving outside the visScrollRect?
- if ((vScrollDelta > 0 &&
- (curIdleSpriteP->destFrameRect.top < visScrollRectP->top) &&
- (curIdleSpriteP->destFrameRect.bottom > spriteWorldP->oldVisScrollRect.top)) ||
- (vScrollDelta < 0 &&
- (curIdleSpriteP->destFrameRect.top < spriteWorldP->oldVisScrollRect.bottom) &&
- (curIdleSpriteP->destFrameRect.bottom > visScrollRectP->bottom)) )
- {
- // Erase piece of idle sprite outside of visScrollRect
- tempDstRect = curSpriteP->oldFrameRect;
-
- // Get section of sprite outside visScrollRect
- if (vScrollDelta > 0)
- {
- if (tempDstRect.bottom > visScrollRectP->top)
- tempDstRect.bottom = visScrollRectP->top;
- }
- else
- {
- if (tempDstRect.top < visScrollRectP->bottom)
- tempDstRect.top = visScrollRectP->bottom;
- }
-
- // Clip tempDstRect with oldVisScrollRect
- if (tempDstRect.top < spriteWorldP->oldVisScrollRect.top)
- tempDstRect.top = spriteWorldP->oldVisScrollRect.top;
- if (tempDstRect.bottom > spriteWorldP->oldVisScrollRect.bottom)
- tempDstRect.bottom = spriteWorldP->oldVisScrollRect.bottom;
- if (tempDstRect.left < spriteWorldP->oldVisScrollRect.left)
- tempDstRect.left = spriteWorldP->oldVisScrollRect.left;
- if (tempDstRect.right > spriteWorldP->oldVisScrollRect.right)
- tempDstRect.right = spriteWorldP->oldVisScrollRect.right;
-
- // Make the rect local to the offscreen area
- tempDstRect.top -= spriteWorldP->vertScrollRectOffset;
- tempDstRect.bottom -= spriteWorldP->vertScrollRectOffset;
- tempDstRect.left -= spriteWorldP->horizScrollRectOffset;
- tempDstRect.right -= spriteWorldP->horizScrollRectOffset;
-
- SWEraseWrappedSprite(spriteWorldP, &tempDstRect);
- }
- }
-
-
- // Is the idle sprite visible on the screen?
- if (curSpriteP->destRectIsVisible)
- {
- // Add sprite to idle sprite list
- if (headIdleSpriteP == NULL)
- headIdleSpriteP = curSpriteP;
-
- if (curIdleSpriteP != NULL)
- curIdleSpriteP->nextIdleSpriteP = curSpriteP;
-
- curIdleSpriteP = curSpriteP;
- }
- }
-
- curSpriteP = curSpriteP->nextSpriteP;
- }
-
- curSpriteLayerP = curSpriteLayerP->nextSpriteLayerP;
- }
-
- if (curActiveSpriteP != NULL)
- curActiveSpriteP->nextActiveSpriteP = NULL;
-
- if (curIdleSpriteP != NULL)
- curIdleSpriteP->nextIdleSpriteP = NULL;
-
-
-
- // This section of code iterates through the idle sprite list, drawing the tiny
- // sliver of any idle sprites that have just entered the visScrollRect.
- curIdleSpriteP = headIdleSpriteP;
- while (curIdleSpriteP != NULL)
- {
- // Draw vertical piece of idle sprite if it is coming into the visScrollRect.
- if ((vScrollDelta > 0 &&
- (curIdleSpriteP->destFrameRect.top < visScrollRectP->bottom) &&
- (curIdleSpriteP->destFrameRect.bottom > spriteWorldP->oldVisScrollRect.bottom) ) ||
- (vScrollDelta < 0 &&
- (curIdleSpriteP->destFrameRect.top < spriteWorldP->oldVisScrollRect.top) &&
- (curIdleSpriteP->destFrameRect.bottom > visScrollRectP->top)) )
- {
- tempDstRect = curIdleSpriteP->destOffscreenRect;
- tempSrcRect = curIdleSpriteP->clippedSourceRect;
-
- // Determine whether scrolling up or down, then get
- // section of sprite outside oldVisScrollRect.
- if (vScrollDelta < 0)
- {
- // Scrolling up, so get section above oldVisScrollRect
- if (tempDstRect.bottom > spriteWorldP->oldVisScrollRect.top)
- {
- tempSrcRect.bottom += spriteWorldP->oldVisScrollRect.top -
- tempDstRect.bottom;
- tempDstRect.bottom = spriteWorldP->oldVisScrollRect.top;
- }
- }
- else
- {
- // Scrolling down, so get section below oldVisScrollRect
- if (tempDstRect.top < spriteWorldP->oldVisScrollRect.bottom)
- {
- tempSrcRect.top += spriteWorldP->oldVisScrollRect.bottom -
- tempDstRect.top;
- tempDstRect.top = spriteWorldP->oldVisScrollRect.bottom;
- }
- }
-
- // Make the sprite's rect local to the offscreen area
- tempDstRect.top -= spriteWorldP->vertScrollRectOffset;
- tempDstRect.bottom -= spriteWorldP->vertScrollRectOffset;
- tempDstRect.left -= spriteWorldP->horizScrollRectOffset;
- tempDstRect.right -= spriteWorldP->horizScrollRectOffset;
-
- // Draw the sprite in the work area
- SWDrawWrappedSprite(curIdleSpriteP, spriteWorldP->workFrameP,
- &tempSrcRect, &tempDstRect);
-
- // Draw tiles above sprite
- if (spriteWorldP->tilingIsOn &&
- curIdleSpriteP->tileDepth <= spriteWorldP->lastActiveTileLayer)
- {
- tempDstRect.top += spriteWorldP->vertScrollRectOffset;
- tempDstRect.bottom += spriteWorldP->vertScrollRectOffset;
- tempDstRect.left += spriteWorldP->horizScrollRectOffset;
- tempDstRect.right += spriteWorldP->horizScrollRectOffset;
- SWDrawTilesAboveSprite(spriteWorldP, &tempDstRect, curIdleSpriteP->tileDepth);
- }
- }
-
-
- // Draw horizontal piece of idle sprite if it is coming into the visScrollRect.
- if ((hScrollDelta > 0 &&
- (curIdleSpriteP->destFrameRect.left < visScrollRectP->right) &&
- (curIdleSpriteP->destFrameRect.right > spriteWorldP->oldVisScrollRect.right) ) ||
- (hScrollDelta < 0 &&
- (curIdleSpriteP->destFrameRect.left < spriteWorldP->oldVisScrollRect.left) &&
- (curIdleSpriteP->destFrameRect.right > visScrollRectP->left)) )
- {
- tempDstRect = curIdleSpriteP->destOffscreenRect;
- tempSrcRect = curIdleSpriteP->clippedSourceRect;
-
- // Determine whether scrolling left or right, then get
- // section of sprite outside oldVisScrollRect.
- if (hScrollDelta < 0)
- {
- // Scrolling left, so get section to the left of oldVisScrollRect
- if (tempDstRect.right > spriteWorldP->oldVisScrollRect.left)
- {
- tempSrcRect.right += spriteWorldP->oldVisScrollRect.left -
- tempDstRect.right;
- tempDstRect.right = spriteWorldP->oldVisScrollRect.left;
- }
- }
- else
- {
- // Scrolling right, so get section to the right of oldVisScrollRect
- if (tempDstRect.left < spriteWorldP->oldVisScrollRect.right)
- {
- tempSrcRect.left += spriteWorldP->oldVisScrollRect.right -
- tempDstRect.left;
- tempDstRect.left = spriteWorldP->oldVisScrollRect.right;
- }
- }
-
-
- // Make the sprite's rect local to the offscreen area
- tempDstRect.top -= spriteWorldP->vertScrollRectOffset;
- tempDstRect.bottom -= spriteWorldP->vertScrollRectOffset;
- tempDstRect.left -= spriteWorldP->horizScrollRectOffset;
- tempDstRect.right -= spriteWorldP->horizScrollRectOffset;
-
- // Draw the sprite in the work area
- SWDrawWrappedSprite(curIdleSpriteP, spriteWorldP->workFrameP,
- &tempSrcRect, &tempDstRect);
-
- // Draw tiles above sprite
- if (spriteWorldP->tilingIsOn &&
- curIdleSpriteP->tileDepth <= spriteWorldP->lastActiveTileLayer)
- {
- tempDstRect.top += spriteWorldP->vertScrollRectOffset;
- tempDstRect.bottom += spriteWorldP->vertScrollRectOffset;
- tempDstRect.left += spriteWorldP->horizScrollRectOffset;
- tempDstRect.right += spriteWorldP->horizScrollRectOffset;
- SWDrawTilesAboveSprite(spriteWorldP, &tempDstRect, curIdleSpriteP->tileDepth);
- }
- }
-
- curIdleSpriteP = curIdleSpriteP->nextIdleSpriteP;
- }
-
-
- // update flagged background rects
- curRectStructP = spriteWorldP->headUpdateRectP;
- while ( curRectStructP != NULL )
- {
- tempDstRect = curRectStructP->updateRect;
-
- // Make the rect local to the offscreen area
- tempDstRect.top -= spriteWorldP->vertScrollRectOffset;
- tempDstRect.bottom -= spriteWorldP->vertScrollRectOffset;
- tempDstRect.left -= spriteWorldP->horizScrollRectOffset;
- tempDstRect.right -= spriteWorldP->horizScrollRectOffset;
-
- // We're not really erasing a sprite, just copying while wrapping
- SWEraseWrappedSprite(spriteWorldP, &tempDstRect);
- curRectStructP = curRectStructP->nextRectStructP;
- }
-
- // Redraw idle sprites that were erased by a tile
- if (spriteWorldP->numTilesChanged > 0)
- SWCheckWrappedIdleSpritesWithTiles(spriteWorldP, headIdleSpriteP);
-
- // Redraw idle sprites that were erased by an updateRect
- if (spriteWorldP->headUpdateRectP != NULL)
- SWCheckWrappedIdleSpritesWithRects(spriteWorldP, headIdleSpriteP);
-
- // Call the postEraseCallBack
- if (spriteWorldP->postEraseCallBack != NULL)
- (*spriteWorldP->postEraseCallBack)(spriteWorldP);
-
-
- //-----------------draw the sprites-------------------
-
- curSpriteLayerP = spriteWorldP->headSpriteLayerP;
-
- // iterate through the layers in this world
- while (curSpriteLayerP != NULL)
- {
- curSpriteP = curSpriteLayerP->headSpriteP;
-
- // iterate through the sprites in this layer
- while (curSpriteP != NULL)
- {
- if (curSpriteP->isVisible)
- {
- // Make the sprite's rect local to the offscreen area
- curSpriteP->destOffscreenRect.top -= spriteWorldP->vertScrollRectOffset;
- curSpriteP->destOffscreenRect.bottom -= spriteWorldP->vertScrollRectOffset;
- curSpriteP->destOffscreenRect.left -= spriteWorldP->horizScrollRectOffset;
- curSpriteP->destOffscreenRect.right -= spriteWorldP->horizScrollRectOffset;
-
- if (curSpriteP->needsToBeDrawn)
- {
- // Is the sprite visible on the screen?
- if (curSpriteP->destRectIsVisible)
- {
- gSWCurrentSpriteBeingDrawn = curSpriteP;
-
- // Draw the sprite in the work area
- SWDrawWrappedSprite(curSpriteP, spriteWorldP->workFrameP,
- &curSpriteP->clippedSourceRect,
- &curSpriteP->destOffscreenRect);
-
- gSWCurrentSpriteBeingDrawn = NULL;
-
- // Draw tiles above sprite
- if (spriteWorldP->tilingIsOn &&
- curSpriteP->tileDepth <= spriteWorldP->lastActiveTileLayer)
- {
- tempDstRect = curSpriteP->destOffscreenRect;
- tempDstRect.top += spriteWorldP->vertScrollRectOffset;
- tempDstRect.bottom += spriteWorldP->vertScrollRectOffset;
- tempDstRect.left += spriteWorldP->horizScrollRectOffset;
- tempDstRect.right += spriteWorldP->horizScrollRectOffset;
- SWDrawTilesAboveSprite(spriteWorldP, &tempDstRect, curSpriteP->tileDepth);
- }
- }
- }
- else
- {
- // Is the idle sprite visible on the screen?
- if (curSpriteP->destRectIsVisible)
- {
- SWCheckWrappedIdleSpriteOverlap(spriteWorldP,
- curSpriteP, headActiveSpriteP);
- }
- }
- }
-
-
- ///
- // This is where a lot of code was removed.
- // (most of it moved to SWFinishMultiScreenAnimation)
- ///
-
-
- curSpriteP = curSpriteP->nextSpriteP;
- }
-
- curSpriteLayerP = curSpriteLayerP->nextSpriteLayerP;
- }
-
- spriteWorldP->oldVisScrollRect = spriteWorldP->visScrollRect;
-
-
- // Call the postDrawCallBack
- if (spriteWorldP->postDrawCallBack != NULL)
- (*spriteWorldP->postDrawCallBack)(spriteWorldP);
-
-
- //-----------------update the screen--------------------
-
- // Set the port to the window
- SetGWorld(spriteWorldP->windowFrameP->framePort, nil);
-
- if (spriteWorldP->usingVBL)
- {
- spriteWorldP->vblTaskRec.hasVBLFired = false;
- while ( !spriteWorldP->vblTaskRec.hasVBLFired )
- {}
- }
-
- // Copy offscreen area to screen while wrapping
- SWWrapWorkAreaToFrame(spriteWorldP, spriteWorldP->windowFrameP, &spriteWorldP->windRect);
-
-
- // dispose of flagged background rects
- nextRectStructP = spriteWorldP->headUpdateRectP;
- while ( nextRectStructP != NULL )
- {
- curRectStructP = nextRectStructP;
- nextRectStructP = curRectStructP->nextRectStructP;
- DisposePtr( (Ptr)curRectStructP );
- }
- spriteWorldP->headUpdateRectP = NULL;
-
- spriteWorldP->numTilesChanged = 0;
-
-
- // Remove the deadSpriteLayer if we added it earlier.
- if ( spriteWorldP->deadSpriteLayerP->headSpriteP != NULL )
- {
- SWRemoveSpriteLayer(spriteWorldP, spriteWorldP->deadSpriteLayerP);
- }
-
- gSWCurrentSpriteWorld = NULL;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWFinishMultiScreenAnimation
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWFinishMultiScreenAnimation(
- SpriteWorldPtr spriteWorldP)
- {
- register SpriteLayerPtr curSpriteLayerP;
- register SpritePtr curSpriteP;
-
-
- curSpriteLayerP = spriteWorldP->headSpriteLayerP;
-
- // iterate through the layers in this world
- while (curSpriteLayerP != NULL)
- {
- curSpriteP = curSpriteLayerP->headSpriteP;
-
- // iterate through the sprites in this layer
- while (curSpriteP != NULL)
- {
- // Set last rect to current rect
- curSpriteP->oldFrameRect = curSpriteP->destFrameRect;
-
- curSpriteP->needsToBeDrawn = false;
- curSpriteP->needsToBeErased = false;
-
- curSpriteP = curSpriteP->nextSpriteP;
- }
-
- curSpriteLayerP = curSpriteLayerP->nextSpriteLayerP;
- }
- }
-
-